Repository navigation
novatek: the mask ROM's fallback and UART download, so defib recovers a blank NT9856x - #225
Conversation
PR Summary by QodoModel NT9856x mask-ROM fallback and UART recovery
AI Description
Diagram
High-Level Assessment
Files changed (9)
|
Code Review by Qodo
1.
|
… a blank NT9856x nvt-bootrom copied the flash's loader, or a boot-file=, and nothing else: the ROM's own recovery was not modelled. On NA51089 it now is, as read from a dump of the ROM and the NT9856x ROM code application note, and checked against an NT98562 and an NT98566 in the lab: - rom-fallback=on, or a boot-strap= that is not a flash strap, and a flash with no valid loader: the CPU parks in WFI while the ROM tries flash, SD, Ethernet, USB and UART, and again from SD, printing the silicon's letters (NPIp>K9 S1K2 HE...s100FX S1 ... K: U K:). The loader check is the ROM's: word 1 the address, word 9 the size, 0xAA55 at 0x30, halfwords plus indices summing to 0. Then "T" and the jump. - The UART stage is the ROM's command engine: 16-byte 0xC0 CDBs, IS_NVT (echo and the chip word), OPEN_DEVICE (stops its 30 s timeout), ADDR_READ, ADDR_WRITE (acts even with a bad checksum), WRLOADER and WAIT_DONE. Its quirks are kept: every 16 bytes are one command, nothing resyncs, and the WRLOADER payload is decoded as commands too. Bytes that arrive outside the stage are dropped, as a full FIFO drops them. - Ethernet sends nothing yet: the stage behaves like a network with no DHCP server, so the fallback goes on to USB and UART. - rom-fast=on cuts the DHCP and USB waits tenfold, not the UART window. OpenIPC's defib (OpenIPC/defib#169) recovers it unmodified: the real wrloader.bin and FW98562T.BIN from novatek-recovery.tar.gz go in over socket://, and U-Boot from RAM answers at its prompt, on nt98562 and nt98566, through the straps (boot-strap=0xc) and through the fallback from a blank NOR. qemu-boot/test-novatek-recovery.sh does both, and a new CI job runs it. test-novatek.py gains the engine's cases (stray byte out of step, bad checksums, a WRLOADER-shaped payload chunk moving the store, the jump) and the fallback's letters: 794 checks pass.
…raps, defib pinned Review follow-ups: - A flash loader whose header names another SRAM base no longer passes for valid with the fallback on: rom_flash_loader_ok() checks word 1, as the fallback's own check does before the jump. - nvt_rom_strap_is_flash() follows rom_first_source(): every strap but SD (1), Ethernet (4), USB (5, 0xB) and UART (0xC) starts from flash, so a reserved strap no longer turns the fallback on. - CI installs a fixed defib commit, OpenIPC/defib master after #170, not whatever its master holds.
46ba5c4 to
b011f36
Compare
…#226) * novatek: the mask ROM's Ethernet boot, DHCP and TFTP through nvt-eqos The fallback's Ethernet stage (#225) sent nothing. It is now the NA51089 ROM's DHCP and TFTP client, as read from a dump of the ROM and seen on an NT98562 on a real LAN: - A MAC of 00:00:00 and three random bytes, new every boot. DHCPDISCOVER every 5 s. - The first broadcast offer is taken; a unicast one, to an address it has not configured, is dropped, as silicon dropped dnsmasq's. - DHCPREQUEST, the ACK, an ARP request for the next-server, then one TFTP read request for loader.bin from port 2962, to the offer's MAC. - Then it waits for DATA from that server with no timeout and no retransmission, so a network DHCP server that wins the race holds it for good. A short block ends it, then the loader check. - The letters are silicon's: aOfIP <ip> SRV <srv>, MSK, bS2, cAkS3S4, CD for ARP, t<block>, Dn, T. The ROM drives nvt-eqos through a new hook: attached, every frame goes to it instead of the rings, and it sends on the NIC's queue; it detaches before the jump, and the loader brings the MAC up as before. Attaching flushes the queue, or a tap backend that stopped polling while the MAC could not receive never starts again. defib's Ethernet recovery (OpenIPC/defib#170, #171) runs against it unmodified over a tap: the ROM takes defib's offer, fetches loader.bin, the real Ethernet loader then does its own DHCP and fetches the U-Boot pack, and U-Boot from RAM answers at its prompt, on nt98562 and nt98566. qemu-boot/test-novatek-recovery.sh gains that third way in, and CI runs it (sudo for the tap and ports 67/69), with defib pinned to 74e1bcc. test-novatek.py drives the ROM over a UDP socket netdev with no root: a unicast offer dropped, a broadcast one taken, the ARP and the single read request to the offering MAC, no retransmission while it waits, and one short block running the loader. 802 checks pass. * novatek: the DHCPREQUEST names the offer's server, and the test leaves a caller's tap alone Review follow-ups: - The ROM's DHCPREQUEST carries the offer's own server identifier (option 54) and no longer the next-server, which may be a separate TFTP host; the next-server stays the one TFTP is asked. - test-novatek-recovery.sh changes a pre-existing tap only by adding its address if missing, and takes back just that; a tap it made, it deletes.
The NA51089 ROM model now runs the silicon's own recovery when the flash has no valid loader: the fallback order and console letters, and the UART download engine with its quirks. The ROM and its behaviour were read from a dump and the ROM code application note, and checked against an NT98562 and an NT98566.
What
defib burn(OpenIPC/defib#169) does against it, unmodified:wrloader.binand theFW98562T.BINpack oversocket://;boot-strap=0xc) and through the fallback from a blank NOR.Tests:
qemu-boot/test-novatek-recovery.shruns defib both ways in, and a new CI job runs it.test-novatek.pycovers the UART engine and the fallback's letters; all 794 checks pass.The Ethernet stage (DHCP/TFTP through
nvt-eqos) comes in a follow-up PR, after this one merges.